#ifndef INLGWPGKWEOIT_58395JFLSG_RUTOOJVN_HRYOQOJNO6847201
#define INLGWPGKWEOIT_58395JFLSG_RUTOOJVN_HRYOQOJNO6847201

#include <base/Keywords.h>

namespace details
{
    template <typename T>
    struct Role
    {
        virtual ~Role() {}
    };
}

#define DEFINE_ROLE(type) struct type : ::details::Role<type>
#define ROLE(type) get##role()
#define ROLE_PROTO_TYPE(role) role& ROLE(role) const
#define USE_ROLE(role) virtual ROLE_PROTO_TYPE(role) = 0
#define HAS_ROLE(role) USE_ROLE(role)

//////////////////////////////////////////////////////////////////
#define IMPL_ROLE(role)                                       \
ROLE_PROTO_TYPE(role)                                         \
{                                                             \
   return const_cast<role&>(static_cast<const role&>(*this)); \
}

#endif

